<?php
/**
 * Zend Framework
 *
 * LICENSE
 *
 * This source file is subject to the new BSD license that is bundled
 * with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://framework.zend.com/license/new-bsd
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@zend.com so we can send you a copy immediately.
 *
 * @category   Zend
 * @package    Zend_Auth
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 * @version    $Id: Auth.php 23775 2011-03-01 17:25:24Z ralph $
 */

/**
 * @category   Zend
 * @package    Zend_Auth
 * @copyright  Copyright (c) 2005-2011 Zend Technologies USA Inc. (http://www.zend.com)
 * @license    http://framework.zend.com/license/new-bsd     New BSD License
 */
class Zend_Auth {
	/**
	 * Singleton instance
	 *
	 * @var Zend_Auth
	 */
	protected static $_instance = null;
	
	/**
	 * Persistent storage handler
	 *
	 * @var Zend_Auth_Storage_Interface
	 */
	protected $_storage = null;
	
	/**
	 * Singleton pattern implementation makes "new" unavailable
	 *
	 * @return void
	 */
	protected function __construct() {
	}
	
	/**
	 * Singleton pattern implementation makes "clone" unavailable
	 *
	 * @return void
	 */
	protected function __clone() {
	}
	
	/**
	 * Returns an instance of Zend_Auth
	 *
	 * Singleton pattern implementation
	 *
	 * @return Zend_Auth Provides a fluent interface
	 */
	public static function getInstance() {
		if (null === self::$_instance) {
			self::$_instance = new self ();
		}
		
		return self::$_instance;
	}
	
	/**
	 * Returns the persistent storage handler
	 *
	 * Session storage is used by default unless a different storage adapter has been set.
	 *
	 * @return Zend_Auth_Storage_Interface
	 */
	public function getStorage() {
		if (null === $this->_storage) {
			/**
			 * @see Zend_Auth_Storage_Session
			 */
			require_once 'Zend/Auth/Storage/Session.php';
			$this->setStorage ( new Zend_Auth_Storage_Session () );
		}
		
		return $this->_storage;
	}
	
	/**
	 * Sets the persistent storage handler
	 *
	 * @param  Zend_Auth_Storage_Interface $storage
	 * @return Zend_Auth Provides a fluent interface
	 */
	public function setStorage(Zend_Auth_Storage_Interface $storage) {
		$this->_storage = $storage;
		return $this;
	}
	
	/**
	 * Authenticates against the supplied adapter
	 *
	 * @param  Zend_Auth_Adapter_Interface $adapter
	 * @return Zend_Auth_Result
	 */
	public function authenticate(Zend_Auth_Adapter_Interface $adapter) {
		$result = $adapter->authenticate ();
		
		/**
		 * ZF-7546 - prevent multiple succesive calls from storing inconsistent results
		 * Ensure storage has clean state
		 */
		if ($this->hasIdentity ()) {
			$this->clearIdentity ();
		}
		
		if ($result->isValid ()) {
			$this->getStorage ()->write ( $result->getIdentity () );
		}
		
		return $result;
	}
	
	/**
	 * Returns true if and only if an identity is available from storage
	 *
	 * @return boolean
	 */
	public function hasIdentity() {
		return ! $this->getStorage ()->isEmpty ();
	}
	
	/**
	 * Returns the identity from storage or null if no identity is available
	 *
	 * @return mixed|null
	 */
	public function getIdentity() {
		$storage = $this->getStorage ();
		
		if ($storage->isEmpty ()) {
			return null;
		}
		
		return $storage->read ();
	}
	
	/**
	 * Clears the identity from persistent storage
	 *
	 * @return void
	 */
	public function clearIdentity() {
		$this->getStorage ()->clear ();
	}
}
